SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00003 1 08-24-9413:26ALL MICHAEL GALLIAS DATE/TIME Procedures SWAG9408 ╖zCÆ 108 ╬N {ππVarious Date and Time ProceduresππRev. 1.06ππ(c) Copyright 1994, Michael GalliasππTarget: Real, Protected, Windowsππ}ππ{$V-} {$B-}ππUnit Calendar;ππInterfaceππ{$IFDEF WINDOWS}ππUses WinDos, PasStr;ππ{$ELSE}ππUses Dos, PasStr;ππ{$ENDIF}ππConstπ dts_DDMYYYY = 1;π dts_DDMMYYYY = 2;π dts_DDMMMYYYY = 3;ππTypeπ TimeDate = Recordπ Year,π Month,π Day,π WeekDay,π Hour,π Min,π Sec,π ms :Word;π End;ππ DayNameString = String[9];π DayNameArray = Array [0..6] of DayNameString;π MonthNameString = String[10];π MonthNameArray = Array [1..12] of MonthNameString;π MonthAbrString = String[3];π MonthAbrArray = Array [1..12] of MonthAbrString;ππConstπ DayName : DayNameArray =π ('Sunday', 'Monday', 'Tuesday', 'Wednesday',π 'Thursday', 'Friday', 'Saturday');ππ MonthName : MonthNameArray =π ('January', 'February', 'March', 'April', 'May',π 'June', 'July', 'August', 'September',π 'October', 'November', 'December');ππ MonthAbr : MonthNameArray =π ('Jan', 'Feb', 'Mar', 'Apr', 'May',π 'Jun', 'Jul', 'Aug', 'Sep',π 'Oct', 'Nov', 'Dec');ππProcedure StringToDate (Strg:String; Var Date:TimeDate;π Const Style:Byte; Var Code:Integer);πProcedure DateToString (Date:TimeDate; Var Strg:String; Const Style:Byte);πProcedure StringToTime (Strg:String; Var Time:TimeDate; Var Code:Integer);πProcedure TimeToString (Time:TimeDate; Var Strg:String);πProcedure MMDDToDDMM (DateIn:String; Var DateOut:String);πProcedure GetTimeDate (Var Time:TimeDate);πProcedure PredMin (Const TimeIn:TimeDate; Var TimeOut:TimeDate);πProcedure PredHour (Const TimeIn:TimeDate; Var TimeOut:TimeDate);πProcedure UntotalDays (Total:LongInt; Var Date:TimeDate);πProcedure DayOfWeek (Var Date:TimeDate);πFunction DayOfYear (Const Date:TimeDate):Word;πFunction TotalMonths (Const Date:TimeDate):LongInt;πFunction TotalDays (Const Date:TimeDate):LongInt;πFunction TotalHalfHrs (Const Time:TimeDate):Byte;πFunction TotalMinutes (Const Time:TimeDate):Word;πFunction TotalSeconds (Const Time:TimeDate):LongInt;πFunction Totalms (Const Time:TimeDate):LongInt;πFunction ChangedTime (Const Time1, Time2:TimeDate):Boolean;πFunction ChangedTimeDate (Const Time1, Time2:TimeDate):Boolean;πFunction ChangedDate (Const Date1, Date2:TimeDate):Boolean;πFunction DaysInMonth (Month:Byte;Year:Word):Byte;πFunction DaysInYear (Year:Word):Word;ππImplementationππProcedure StringToDate(Strg:String;Var Date:TimeDate;π Const Style:Byte; Var Code:Integer);ππVarπ SY,SM,SD,ST :String;π AY,AM,AD,AT :LongInt;ππBeginπ Code:=0;π Case Style Ofπ dts_DDMMYYYY:π Beginπ Strg:=Strg+'/';π SY:='';π SM:='';π SD:='';ππ SD:=Copy(Strg,1,Pos('/',Strg)-1);π Delete(Strg,1,Pos('/',Strg));ππ If Pos('/',Strg)>0 Thenπ Beginπ SM:=Copy(Strg,1,Pos('/',Strg)-1);π Delete(Strg,1,Pos('/',Strg));π End;ππ If Pos('/',Strg)>0 Thenπ Beginπ SY:=Copy(Strg,1,Pos('/',Strg)-1);π Delete(Strg,1,Pos('/',Strg));π End;ππ If SY<>'' Thenπ Beginπ If Length(SY)<3 Then SY:='19'+SY;π Val(SY,AY,Code);π If (AY<1991) Or (AY>1999) Then Code:=6;π Endπ Elseπ Code:=6;ππ If SM<>'' Thenπ Beginπ Val(SM,AM,Code);π If (AM<1) Or (AM>12) Then Code:=3;π Endπ Elseπ Code:=3;ππ If SD<>'' Thenπ Beginπ Val(SD,AD,Code);π If (AD<1) Or (AD>DaysInMonth(AM,AY)) Then Code:=1;π Endπ Elseπ Code:=1;π End;π dts_DDMMMYYYY,π dts_DDMYYYY:π Beginπ Strg:=Strg+' ';π SD:=Copy(Strg,1,Pos(' ',Strg)-1);π Delete(Strg,1,Pos(' ',Strg));π SM:=Copy(Strg,1,Pos(' ',Strg)-1);π Delete(Strg,1,Pos(' ',Strg));π SY:=Copy(Strg,1,Pos(' ',Strg)-1);π If (SD='') Or (SM='') Or (SY='') Thenπ Code:=99π Elseπ Beginπ UpperCase(SM,SM);π AT:=0;π Repeatπ Inc(AT);π UpperCase(MonthName[AT],ST);π Until (AT=12) Or (ST=SM);π If ST<>SM Thenπ Beginπ AT:=0;π Repeatπ Inc(AT);π UpperCase(MonthAbr[AT],ST);π Until (AT=12) Or (ST=SM);π End;π If ST=SM Then AM:=AT Else Code:=3;π If Code=0 Thenπ Beginπ If Length(SY)<3 Then SY:='19'+SY;π Val(SY,AY,Code);π If (AY<1991) Or (AY>1999) Then Code:=6;π End;π If Code=0 Thenπ Beginπ Val(SD,AD,Code);π If (AD<1) Or (AD>DaysInMonth(AM,AY)) Then Code:=1;π End;π End;π End;π End;π If Code=0 Thenπ Beginπ Date.Day :=AD;π Date.Month :=AM;π Date.Year :=AY;π End;πEnd;ππProcedure DateToString(Date:TimeDate;Var Strg:String;Const Style:Byte);ππVarπ Temp:String[20];ππBeginπ Case Style Ofπ dts_DDMYYYY:π Beginπ Str(Date.Day:2,Strg);π SpacesToZeros(Strg,Strg);π Temp:=MonthName[Date.Month];π Strg:=Strg+' '+Temp+' ';π Str(Date.Year:4,Temp);π Strg:=Strg+Temp;π End;π dts_DDMMYYYY:π Beginπ Str(Date.Day:2,Strg);π Str(Date.Month:2,Temp);π Strg:=Strg+'/'+Temp+'/';π Str(Date.Year:4,Temp);π Strg:=Strg+Temp;π SpacesToZeros(Strg,Strg);π End;π dts_DDMMMYYYY:π Beginπ Str(Date.Day:2,Strg);π SpacesToZeros(Strg,Strg);π Temp:=MonthAbr[Date.Month];π Strg:=Strg+' '+Temp+' ';π Str(Date.Year:4,Temp);π Strg:=Strg+Temp;π End;π End;πEnd;ππProcedure StringToTime(Strg:String;Var Time:TimeDate;Var Code:Integer);ππVarπ SH,SM,SS:String[10];π AH,AM,AS:LongInt;ππBeginπ Strg:=Strg+':';π SH:='';π SM:='';π SS:='';ππ SH:=Copy(Strg,1,Pos(':',Strg)-1);π Delete(Strg,1,Pos(':',Strg));ππ If Pos(':',Strg)>0 Thenπ Beginπ SM:=Copy(Strg,1,Pos(':',Strg)-1);π Delete(Strg,1,Pos(':',Strg));π End;ππ If Pos(':',Strg)>0 Thenπ Beginπ SS:=Copy(Strg,1,Pos(':',Strg)-1);π Delete(Strg,1,Pos(':',Strg));π End;ππ If SH<>'' Thenπ Beginπ Val(SH,AH,Code);π If (Code>0) Or (AH<0) Or (AH>23) Then Exit;π Endπ Elseπ AH:=Time.Hour;ππ If SM<>'' Thenπ Beginπ Val(SM,AM,Code);π If (Code>0) Or (AM<0) Or (AM>59) Then Exit;π Endπ Elseπ AM:=Time.Min;ππ If SS<>'' Thenπ Beginπ Val(SS,AS,Code);π If (Code>0) Or (AS<0) Or (AS>59) Then Exit;π Endπ Elseπ AS:=Time.Sec;ππ Time.Hour :=AH;π Time.Min :=AM;π Time.Sec :=AS;πEnd;ππProcedure TimeToString(Time:TimeDate;Var Strg:String);ππVarπ Temp:String[10];ππBeginπ Str(Time.Hour:2,Strg);π Str(Time.Min:2,Temp);π Strg:=Strg+':'+Temp+':';π Str(Time.Sec:2,Temp);π Strg:=Strg+Temp;π SpacesToZeros(Strg,Strg);πEnd;ππProcedure MMDDToDDMM(DateIn:String;Var DateOut:String);ππVarπ First :String[12];π P :Byte;ππBeginπ If DateIn='' Thenπ Beginπ DateOut:='';π Exit;π End;ππ DateOut:='';π DateIn:=DateIn+' ';π P:=Max(Pos(' ',DateIn),Pos('/',DateIn));π First:=Copy(DateIn,1,P);π Delete(DateIn,1,P);ππ Repeatπ P:=Max(Pos(' ',DateIn),Pos('/',DateIn));π DateOut:=DateOut+Copy(DateIn,1,P);π Delete(DateIn,1,P);π Until Length(DateIn)=0;π P:=Max(Pos(' ',DateOut),Pos('/',DateOut));π Insert(First,DateOut,P);πEnd;ππProcedure GetTimeDate(Var Time:TimeDate);πBeginπ With Time doπ Beginπ GetTime(Hour,Min,Sec,ms);π GetDate(Year,Month,Day,WeekDay);π End;πEnd;ππProcedure PredMin(Const TimeIn:TimeDate; Var TimeOut:TimeDate);π{Decreases the Time by one Minute, does not check the date if TimeOut.Day=0.}πBeginπ TimeOut:=TimeIn;π With TimeOut doπ Beginπ If Min>0 Thenπ Dec(Min)π Elseπ Beginπ Min:=59;π If Hour>0 Thenπ Dec(Hour)π Elseπ Beginπ Hour:=23;π If Day>0 Thenπ Beginπ If Day>1 Thenπ Dec(Day)π Elseπ Beginπ If Month>1 Thenπ Dec(Month)π Elseπ Beginπ Month:=12;π If Year>0 Then Dec(Year);π End;π Day:=DaysInMonth(Month,Year);π End;π End;π End;π End;π End;πEnd;ππProcedure PredHour(Const TimeIn:TimeDate; Var TimeOut:TimeDate);π{Decreases the Time by one Hour, does not check the date if TimeOut.Day=0.}πBeginπ TimeOut:=TimeIn;π With TimeOut doπ Beginπ If Hour>0 Thenπ Dec(Hour)π Elseπ Beginπ Hour:=23;π If Day>0 Thenπ Beginπ If Day>1 Thenπ Dec(Day)π Elseπ Beginπ If Month>1 Thenπ Dec(Month)π Elseπ Beginπ Month:=12;π If Year>0 Then Dec(Year);π End;π Day:=DaysInMonth(Month,Year);π End;π End;π End;π End;πEnd;ππProcedure UntotalDays(Total:LongInt; Var Date:TimeDate);ππConstπ t_1000 = 366123; {Number of days from 0 to 1000, inclusive}π t_1500 = 549002;π t_1750 = 640441;π t_1970 = 720908;ππVarπ DIY, DIM :Word;ππBeginπ FillChar(Date,SizeOf(Date),0);ππ If Total>t_1970 Thenπ Beginπ Dec(Total,t_1970);π Date.Year:=1971;π Endπ Elseπ If Total>t_1750 Thenπ Beginπ Dec(Total,t_1750);π Date.Year:=1751;π Endπ Elseπ If Total>t_1500 Thenπ Beginπ Dec(Total,t_1500);π Date.Year:=1501;π Endπ Elseπ If Total>t_1000 Thenπ Beginπ Dec(Total,t_1000);π Date.Year:=1001;π End;ππ DIY:=DaysInYear(Date.Year);π While (Total>DIY) doπ Beginπ Dec(Total,DaysInYear(Date.Year));π Inc(Date.Year);π DIY:=DaysInYear(Date.Year);π End;ππ Date.Month:=1;π For DIY:=1 to 12 doπ Beginπ DIM:=DaysInMonth(DIY,Date.Year);π If Total>DIM Thenπ Beginπ Dec(Total,DIM);π Inc(Date.Month);π End;π End;ππ Date.Day:=Total;πEnd;ππProcedure DayOfWeek(Var Date:TimeDate);π{Sets 'WeekDay' of Date: 1 for Monday, 0 for Sunday}πVarπ A,B,C :Word;π Y,M,D,DOW:Word;ππBeginπ GetDate(Y,M,D,DOW);π SetDate(Date.Year,Date.Month,Date.Day);π GetDate(A,B,C,Date.WeekDay);π SetDate(Y,M,D);πEnd;ππFunction DayOfYear(Const Date:TimeDate):Word;ππVarπ Temp :Word;π X :Byte;ππBeginπ Temp:=Date.Day;π For X:=1 to Date.Month-1 doπ Inc(Temp,DaysInMonth(X,Date.Year));π DayOfYear:=Temp;πEnd;ππFunction TotalMonths(Const Date:TimeDate):LongInt;πBeginπ TotalMonths:=(12 * (Date.Year - 1)) + Date.Month;πEnd;ππFunction TotalDays(Const Date:TimeDate):LongInt;ππ{Returns the total number of days that have elapsed from the year 0, includingπ the current day, e.g. 1 Jan 0 = 1}ππConstπ t_1_1_1970 = 720543;ππVarπ Total:LongInt;π Year :Integer;π Month:Byte;π Start:Integer;ππBeginπ If Date.Year>=1970 Thenπ Beginπ Total:=t_1_1_1970-1;π Start:=1970;π Endπ Elseπ Beginπ Total:=0;π Start:=0;π End;ππ For Year:=Start to Integer(Date.Year)-1 doπ Inc(Total,DaysInYear(Year));ππ For Month:=1 to Date.Month-1 doπ Inc(Total,DaysInMonth(Month,Date.Year));π TotalDays:=Total+Date.Day;πEnd;ππFunction TotalHalfHrs(Const Time:TimeDate):Byte;πBeginπ TotalHalfHrs:=Time.Hour * 2 + (Time.Min Div 30);πEnd;ππFunction TotalMinutes(Const Time:TimeDate):Word;πBeginπ TotalMinutes:=Time.Hour*60+Time.Min;πEnd;ππFunction TotalSeconds(Const Time:TimeDate):LongInt;πBeginπ TotalSeconds:=LongInt(Time.Hour)*60*60+LongInt(Time.Min)*60+LongInt(Time.Sec);πEnd;ππFunction Totalms(Const Time:TimeDate):LongInt;πBeginπ Totalms:=(LongInt(Time.Hour)*60*60+LongInt(Time.Min)*60+LongInt(Time.Sec))*100+LongInt(Time.ms);πEnd;ππFunction ChangedTime(Const Time1, Time2:TimeDate):Boolean;πBeginπ If (Time1.ms =Time2.ms ) Andπ (Time1.Sec =Time2.Sec ) Andπ (Time1.Min =Time2.Min ) Andπ (Time1.Hour=Time2.Hour) Thenπ ChangedTime:=Falseπ Elseπ ChangedTime:=True;πEnd;ππFunction ChangedTimeDate(Const Time1, Time2:TimeDate):Boolean;πBeginπ If (Time1.ms =Time2.ms ) Andπ (Time1.Sec =Time2.Sec ) Andπ (Time1.Min =Time2.Min ) Andπ (Time1.Hour =Time2.Hour ) Andπ (Time1.Day =Time2.Day ) Andπ (Time1.Month=Time2.Month) Andπ (Time1.Year =Time2.Year ) Thenπ ChangedTimeDate:=Falseπ Elseπ ChangedTimeDate:=True;πEnd;ππFunction ChangedDate(Const Date1, Date2:TimeDate):Boolean;πBeginπ If (Date1.Day =Date2.Day ) Andπ (Date1.Month=Date2.Month) Andπ (Date1.Year =Date2.Year ) Thenπ ChangedDate:=Falseπ Elseπ ChangedDate:=True;πEnd;ππFunction DaysInMonth(Month:Byte;Year:Word):Byte;πBeginπ Case Month Ofπ 1:DaysInMonth:=31;π 2:Beginπ If (Year Mod 100)=0 Then {Centuary}π If (Year Mod 400)=0 Thenπ DaysInMonth:=29π Elseπ DaysInMonth:=28π Else {Non Centuary}π If (Year Mod 4)=0 Thenπ DaysInMonth:=29π Elseπ DaysInMonth:=28;π End;π 3:DaysInMonth:=31;π 4:DaysInMonth:=30;π 5:DaysInMonth:=31;π 6:DaysInMonth:=30;π 7:DaysInMonth:=31;π 8:DaysInMonth:=31;π 9:DaysInMonth:=30;π 10:DaysInMonth:=31;π 11:DaysInMonth:=30;π 12:DaysInMonth:=31;π End;πEnd;ππFunction DaysInYear(Year:Word):Word;πBeginπ If DaysInMonth(2,Year)=29 Then DaysInYear:=366 Else DaysInYear:=365;πEnd;ππEnd.π 2 08-24-9413:29ALL MARIUS ELLEN BASM Date Functions SWAG9408 \á 22 ╬N (* Public domainππAuthor: Marius Ellen, Winsum, Groningen, The NetherlandsπFido 2:282/607.2ππ After studying several DayOfWeeks i got sick.π None of them worked really correctly and mostπ had over 15 DIV'/MOD's or * in it.π The Zeller's congruence was the best but theπ routine also contains some range errors. Yearsπ are only valid from 1..6300 and its really slow,π so i wrote my own..πππ About the routines..π routine results valid if year in 0..65536π month in 1..12, and day in 1..28/29/30/31π there is absolute no range checking..π*)ππfunction DayOfWeek(year,month,day:word):word;π{Returns the day of week, 0=Sun..6=Sat}πassembler; {See 1995}πconst mtable:array[0..11] of byte=π (0,3, 3,6, 1,4, 6,2, 5,0, 3,5);πasmπ{(Y+(Y div 4)-(Y div 100)+(Y div 400)-Adjust)mod 7}π mov ax,yearπ mov di,axπ xor bx,bxπ xor cx,cxπ mov si,dayπ dec siπ shr ax,1; adc cl,0 {si+=year div 4}π shr ax,1; adc cl,0π add si,axπ mov bx,25 {si+=year div 100}π xor dx,dxπ div bxπ sub si,axπ shr ax,1; adc ch,0 {si+=year div 400}π shr ax,1; adc ch,0π add si,axπ add si,diπ{if leap-year then decrease days}π mov bx,monthπ cmp bx,2; ja @Noleap {do not adjust}π and cl,cl; jne @NoLeap {year mod 4=0?}π and dx,dx; jne @IsLeap {year mod 100=0?}π and di,di; je @NoLeap {year=0?}π and ch,ch; jne @Noleap {year mod 400=0?}π@IsLeap:dec siπ@Noleap:xor ah,ahπ mov al,byte ptr mTable[bx-1]π add ax,siπ mov bx,7π xor dx,dxπ div bxπ xchg ax,dxπend;ππfunction GetDaysInMonth(Month:Byte;Year:Word):Word;π{Returns the total number of days in a month}πassembler;πasmπ mov bl,Monthπ {What about februari?}π cmp bl,2; jne @Nπ mov ax,Yearπ shr ax,1; jc @Sπ shr ax,1; jc @Sπ {it's a leap-year}π mov cx,25; div cxπ and dx,dx; jne @Tπ {its a century}π and al,3; jne @Sπ @T: {leap}π mov ax,29; jmp @Eπ @S: {noleap}π mov ax,28; jmp @Eπ @N: {Nope, calc moth day's}π mov ax,15π shr bl,1; rcl ax,1π cmp bl,4; jb @Eπ xor ax,1π @E:πend;ππfunction GetDaysInYear(Year:Word):Word;π{Returns the total number of days in a year}πassembler;πasmπ mov ax,2π push axπ push yearπ call GetDaysInMonthπ add ax,(365-28)πend;ππ 3 08-24-9413:54ALL GREG VIGNEAULT RTC direct access... SWAG9408 úñ┴ε 33 ╬N {πMD>What would anyone here recommend as being the best way for DOSπ >protected mode to get the current time of day *without* flippingπ >back to real mode to make a standard DOS call?ππ If your code is allowed to talk to the real-time clock (RTC) chip,π here's some example code to access the RTC directly. The functionsπ work solely with 24-hr time format (if needed, internally by the RTC,π they translate between 12/24-hr times and binary/BCD formats)...π}ππ(*******************************************************************)πPROGRAM RClock; { Get/Set Time/Date directly from RTC chip }π { June 9, 1994. Greg Vigneault }πTYPE Treg = 0..$D; { range for time/date register addresses }π To23 = 0..23; { range for hours }π To59 = 0..59; { range for minutes and seconds }πVAR Yr, Mth, Day, DoW, Hr, Min, Sec : BYTE;ππFUNCTION RTCbusy:BOOLEAN; BEGIN { RTC time/date being updated?... }π Port[$70] := $A;; RTCbusy := (Port[$71] AND 128) = 128;π END {RTCbusy};ππFUNCTION ReadReg (Reg:Treg):BYTE; BEGIN { read an RTC register... }π IF Reg IN [0..9] THEN REPEAT {wait} UNTIL NOT RTCbusy;π Port[$70] := Reg;; ReadReg := Port[$71];π END {ReadReg};ππPROCEDURE WriteReg (Reg:Treg; Data:BYTE); { write RTC reg... }π VAR temp:BYTE; BEGINπ IF Reg IN [0..9] THEN BEGIN { time/date reg? }π REPEAT {wait} UNTIL NOT RTCbusy;π Port[$70] := $B;; temp := Port[$71];; Port[$71] := temp OR $80;π END{IF};π Port[$70] := Reg;; Port[$71] := Data;π IF Reg IN [0..9] THEN BEGINπ Port[$70] := $B;; Port[$71] := temp AND NOT $80;π END{IF};π END {WriteReg};ππFUNCTION BCD2Bin (BCD:BYTE):BYTE; BEGIN { xlate BCD to binary... }π BCD2Bin := (BCD AND $0F) + ((BCD SHR 4) * 10);π END {BCD2Bin};πFUNCTION Bin2BCD (Bin:BYTE):BYTE; BEGIN { xlate binary to BCD... }π Bin2BCD := (Bin MOD 10) OR BYTE((Bin DIV 10) SHL 4);π END {Bin2BCD};ππPROCEDURE GetTime (VAR Hr,Min,Sec:BYTE);π VAR temp:BYTE; BEGINπ Sec := ReadReg(0);; Min := ReadReg(2);π Hr := ReadReg(4);; temp := Hr;; Hr := Hr AND NOT $80;π IF (ReadReg($B) AND 4) <> 4 THEN BEGIN { xlate BCD to bin... }π Sec := BCD2Bin(Sec);; Min := BCD2Bin(Min);; Hr := BCD2Bin(Hr);π END{IF};π IF (ReadReg($B) AND 2) <> 2 THEN { RTC in 12-hr mode?... }π IF (temp AND 128) = 128 { P.M.? }π THEN BEGIN IF (Hr < 12) THEN INC(Hr,12); ENDπ ELSE IF Hr = 12 THEN Hr := 0;π END {GetTime};ππPROCEDURE SetTime (Hr:To23; Min,Sec:To59);π VAR temp:BYTE; BEGINπ temp := BYTE(Hr);π IF (ReadReg($B) AND 2) <> 2 THEN { RTC in 12-hr mode?... }π IF (Hr > 12) THEN DEC(Hr,12) ELSE IF Hr = 0 THEN Hr := 12;π IF (ReadReg($B) AND 4) <> 4 THEN BEGIN { RTC wants BCD format... }π Hr := Bin2BCD(Hr);; Min := Bin2BCD(Min);; Sec := Bin2BCD(Sec);π END{IF};π IF ((ReadReg($B) AND 2)<>2) AND (temp > 11) THEN Hr := Hr OR $80;π WriteReg(0,Sec);; WriteReg(2,Min);; WriteReg(4,Hr);π END {SetTime};ππPROCEDURE GetDate (VAR Yr,Mth,Day:BYTE); BEGINπ Day := ReadReg(7);; Mth := ReadReg(8);; Yr := ReadReg(9);π IF (ReadReg($B) AND 4) <> 4 THEN BEGIN { xlate BCD to binay... }π Day := BCD2Bin(Day);; Mth := BCD2Bin(Mth);; Yr := BCD2Bin(Yr);π END; {IF}π END {GetDate};ππPROCEDURE SetDate (Yr,Mth,Day:BYTE); BEGINπ IF (ReadReg($B) AND 4) <> 4 THEN BEGIN { RTC wants BCD format... }π Day := Bin2BCD(Day);; Mth := Bin2BCD(Mth);; Yr := Bin2BCD(Yr);π END{IF};π WriteReg(7,Day);; WriteReg(8,Mth);; WriteReg(9,Yr);π END {SetDate};ππBEGIN {RClock}π GetTime (Hr,Min,Sec);; GetDate (Yr,Mth,Day);; WriteLn;π Write ('Date is ',Mth,'/',Day,'/',Yr,'. ');π WriteLn ('Time is ',Hr,':',Min:2,':',Sec:2,'.');π Write ('(BTW, your RTC is in ');π IF (ReadReg($B) AND 2) <> 2 THEN Write ('12') ELSE Write ('24');π Write ('-hour mode using ');π IF (ReadReg($B) AND 4) <> 4 THEN Write('BCD') ELSE Write('binary');π WriteLn (' format.)');πEND {RClock}.π